package com.sumainfor.zuul.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.sumainfor.common.util.Constant;
import com.sumainfor.common.util.CustomMap;
import com.sumainfor.common.util.JsonResult;
import com.sumainfor.common.util.RRException;
import com.sumainfor.common.utlis.AuthUtil;
import com.sumainfor.common.utlis.ParamsCommon;
import com.sumainfor.common.wechat.WeChatConfig;
import com.sumainfor.zuul.dao.SysUserDao;
import com.sumainfor.zuul.entity.*;
import com.sumainfor.zuul.service.SysAreaService;
import com.sumainfor.zuul.service.SysDeptService;
import com.sumainfor.zuul.service.SysUserRoleService;
import com.sumainfor.zuul.service.SysUserService;
import com.sumainfor.zuul.util.PageUtils;
import com.sumainfor.zuul.util.Query;
import lombok.extern.log4j.Log4j2;
import net.sf.json.JSONObject;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.crypto.hash.Sha256Hash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors;


/**
 * 系统用户
 */
@Log4j2
@Service("sysUserService")
@Transactional(rollbackFor = Exception.class)
public class SysUserServiceImpl extends ServiceImpl<SysUserDao, SysUserEntity> implements SysUserService {

    @Autowired
    private SysUserRoleService sysUserRoleService;

    @Autowired
    private SysDeptService sysDeptService;

    @Autowired
    private SysUserDao userDao;

    @Autowired
    private SysAreaService areaService;

    @Override
    public List<Integer> queryAllMenuId(Integer userId) {
        return baseMapper.queryAllMenuId(userId);
    }

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        String username = (String) params.get("username");

        Page<SysUserEntity> page = this.selectPage(
                new Query<SysUserEntity>(params).getPage(),
                new EntityWrapper<SysUserEntity>()
                        .like(StringUtils.isNotBlank(username), "login_name", username)
                        .or()
                        .like(StringUtils.isNotBlank(username), "name", username)
                        .addFilterIfNeed(params.get(Constant.SQL_FILTER) != null, (String) params.get(Constant.SQL_FILTER))
        );

        for (SysUserEntity sysUserEntity : page.getRecords()) {
            SysDeptEntity sysDeptEntity = sysDeptService.selectById(sysUserEntity.getDeptId());
            if (sysDeptEntity != null) {
                SysAreaEntity areaEntity = areaService.selectById(sysUserEntity.getAreaId());
                if (areaEntity != null) {
                    sysUserEntity.setAreaName(areaEntity.getName());
                }
                sysUserEntity.setDeptName(sysDeptEntity.getName());
            }
            log.info("----------------------------------------------");
            log.info("----------------------------------------------");
            log.info("----------------------------------------------");
            log.info("----------------------------------------------");
            //根据用户编号获取当前用户绑定的微信资料
            if (sysUserEntity.getUserId() != null && sysUserEntity.getUserId() != 0) {
                SysUserWxEntity UserWx = userDao.getUserWxEntityByUserId(sysUserEntity.getUserId());
                if (UserWx != null) {
                    sysUserEntity.setUserWeChat(UserWx);
                }
            }
        }

        return new PageUtils(page);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void save(SysUserEntity user) {
        if (user.getDeptId() == null) {
            throw new RRException("参数不完整");
        }
        user.setInstm(new Date());
        user.setUserId(null);
        String salt = RandomStringUtils.randomAlphanumeric(20);
        user.setPassword(new Sha256Hash(user.getPassword(), salt).toHex());
        user.setSalt(salt);
        boolean state = this.insert(user);
        if (state == false) {
            throw new RRException("创建用户失败");
        }
        //保存用户与角色关系
        sysUserRoleService.saveOrUpdate(user.getUserId(), user.getRoleIdList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(SysUserEntity user) {
        if (StringUtils.isBlank(user.getPassword())) {
            user.setPassword(null);
        } else {
            SysUserEntity sysUser = this.selectById(user.getUserId());
            if (sysUser == null) {
                throw new RRException("没有查询到这个用户");
            }
            user.setPassword(new Sha256Hash(user.getPassword(), sysUser.getSalt()).toHex());
        }
        boolean state = this.updateById(user);
        if (state == false) {
            throw new RRException("修改失败");
        }

        //保存用户与角色关系
        sysUserRoleService.saveOrUpdate(user.getUserId(), user.getRoleIdList());
    }

    @Override
    public boolean updatePassword(Integer userId, String password, String newPassword) {

        System.out.println("接受的数据");
        System.out.println("userId-------------"+userId);
        System.out.println("password-----------"+password);
        System.out.println("newPassword----------"+newPassword);
        SysUserEntity userEntity = new SysUserEntity();
        userEntity.setPassword(newPassword);
        System.out.println("userEntity------"+userEntity);
        return this.update(userEntity,
                new EntityWrapper<SysUserEntity>().eq("user_id", userId).eq("password", password));
    }

    /**
     * 获取用户信息
     *
     * @return
     */
    @Override
    public List<Map<String, Object>> getUserById(List<String> ids) {
        return userDao.getUserInfoById(ids);
    }

    @Override
    public List<String> queryAllPerms(Integer userId) {
        return baseMapper.queryAllPerms(userId);
    }

    @Override
    public SysUserEntity queryByUserName(String username) {
        return baseMapper.queryByUserName(username);
    }

    @Override
    public void deleteBatch(Long[] userId) {
        boolean state = this.deleteBatchIds(Arrays.asList(userId));
        if (!state) {
            throw new RRException("删除失败");
        }

        for (Long uid : userId) {
            EntityWrapper wrapper = new EntityWrapper();
            wrapper.eq("user_id", uid);
            state = sysUserRoleService.delete(wrapper);
            if (!state) {
                throw new RRException("删除失败");
            }
        }
    }

    @Override
    public List<Map<String, Object>> getUserByRepairsId(List<String> idList) {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("idList", idList);

        return userDao.getUserByRepairsId(params);
    }


    @Override
    public JsonResult getEpcUsersData() {
        return JsonResult.success(userDao.selectUserByEpc());
    }

    /**
     * 获取用户的信息 通过用户的ID
     *
     * @param id
     * @return
     */
    @Override
    public SysUserEntity getUserEntityById(Integer id) {
        SysUserEntity userEntity = baseMapper.getUserEntityById(id);
        List<SysRoleEntity> roleList = baseMapper.selectRoleListByUserId(userEntity.getUserId());
        if (userEntity != null) {
            userEntity.setRoleIdList(roleList.stream().map(item -> item.getRoleId()).collect(Collectors.toList()));
        }
        return userEntity;
    }

    /**
     * 功能描述:
     * 获取所有维修师傅列表
     *
     * @Author zhlu
     * @Description //TODO
     * @Date 2019/5/9 17:21
     */
    @Override
    public List<Map<String, Object>> getRepiarUserList(Map<String, Object> params) {
        return userDao.getRepiarUserList(params);
    }


    /**
     * 查询人员数量
     *
     * @param startTime
     * @param endTime
     * @param deptIds
     * @return
     */
    @Override
    public int selectCountForPeople(String startTime, String endTime, List<Integer> deptIds) {
        return userDao.selectCountForPeople(startTime, endTime, deptIds);
    }

    /**
     * 查询人员信息
     *
     * @param page
     * @param startTime
     * @param endTime
     * @param miId
     * @return
     */
    @Override
    public List<Map<String, Object>> selectPeopleForData(Page page, String startTime, String endTime, List<Integer> miIds) {
        return userDao.selectCountForPeopleData(page, startTime, endTime, miIds);
    }

    /**
     * 功能描述:
     * 根据用户编号解除当前用户微信绑定信息
     *
     * @Author zhlu
     * @Description //TODO
     * @Date 2019/6/8 16:05
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean UnbindUser(Map<String, Object> params) {
        boolean result = false;
        try {
            //修改处理
            Map<String, Object> commonUpdateParms = new HashMap<String, Object>();
//            commonUpdateParms.put("by", ContextUtils.getUserId());//操作人
            commonUpdateParms.put("fnc",
                    this.getClass().getSimpleName() + "." + Thread.currentThread().getStackTrace()[1].getMethodName());// 创建Function名
            ParamsCommon.commonUpdateParms(commonUpdateParms);
            params.putAll(commonUpdateParms);
            //根据用户编号解除当前用户微信绑定信息
            params.put("popenid", null);
            params.put("unionid", null);
            userDao.UnbindUser(params);
            //根据用户编号删除微信资料
            userDao.DeleteUserWx(params);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
        return result;
    }


    /**
     * 获取用户通过unid
     *
     * @param unId
     * @return
     */
    @Override
    public SysUserEntity getUserByUnid(String unId) {
        return baseMapper.getUserByUnid(unId);
    }


    private ReentrantLock wxLock = new ReentrantLock();

    @Override
    public Map<String,Object> getUnionid(String code) {
        try {
            wxLock.tryLock(20, TimeUnit.SECONDS);
            String url = "https://api.weixin.qq.com/sns/oauth2/access_token?"
                    + "appid=" + WeChatConfig.APP_ID
                    + "&secret=" + WeChatConfig.APP_SECRET
                    + "&code=" + code
                    + "&grant_type=authorization_code";
            JSONObject jsonObject = AuthUtil.doGetJson(url);
            log.info("jsonObject---》" + jsonObject);//微信token
            String openid = jsonObject.getString("openid");//拿到用户的opid
            String token = jsonObject.getString("access_token");//拿到微信生成的access_token 两小时刷新一次
            //再次请求微信
            String infoUrl = "https://api.weixin.qq.com/sns/userinfo?"
                    + "access_token=" + token
                    + "&openid=" + openid
                    + "&lang=zh_CN";
            JSONObject infoUrls = AuthUtil.doGetJson(infoUrl);
            log.info("infoUrls---》" + infoUrls);//拿到用户的基本的信息
            String unionid = infoUrls.getString("unionid");
            return CustomMap.create("openId",openid).put("unionid",unionid);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            wxLock.unlock();
        }
        return null;
    }
}


